﻿/*
 * Gradient Control
 * Author : Ashraful Mahmud
 * Web : http://www.yagnaitsolution.ca
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Input;
using Microsoft.VisualBasic;
using System.Windows.Controls.Primitives;
namespace YagnaColor
{
    public class GradientControl : Control
    {
        public enum GradientBrushType
        {
            Linear,
            Radial
        }
        public static readonly RoutedEvent SelectedBrushChangedEvent = EventManager.RegisterRoutedEvent("SelectedBrushChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<Brush>), typeof(GradientControl));

        public static readonly RoutedEvent SelectedColorChangedEvent = EventManager.RegisterRoutedEvent("SelectedColorChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<Color>), typeof(GradientControl));

        private Slider m_ColorSlider;
        private static readonly string ColorSliderName = "PART_ColorSlider";
        private FrameworkElement m_ColorDetail;
        private static readonly string ColorDetailName = "PART_ColorDetail";
        private TranslateTransform markerTransform = new TranslateTransform();
        private Path m_ColorMarker;
        private static readonly string ColorMarkerName = "PART_ColorMarker";
        private ComboBox m_GradientTypeCombo;
        private ComboBox m_InterpModeCombo;
        private ComboBox m_SpreadMethodCombo;
        private static readonly string GradientTypeComboName = "PART_GradientTypeCombo";
        private Canvas m_GradientDetailsLinearGrid;
        private Border m_GradientDetailsLinearBorder;
        private Thumb m_GradientDetailsLinearTopThumb;
        private Thumb m_GradientDetailsLinearBottomThumb;
        private TextBox m_GradientStartPointBox;
        private TextBox m_GradientEndPointBox;
        private TranslateTransform GradientDetailsLinearTopThumbTransform = new TranslateTransform();
        private TranslateTransform GradientDetailsLinearBottomThumbTransform = new TranslateTransform();
        private Border m_GradientStopSlider;
        private Canvas m_GradientStopDeatils;
        private TextBlock m_Gradient_DetailsOffsetText;
        private TextBlock m_Gradient_DetailsColorText;
        private Button m_AddGradientstopButton;
        private Button m_RemoveGradientstopButton;
        private TextBox m_GradientDetailsStopAddBox;
        private TextBox m_GradientDetailsStopRemoveBox;
        private Canvas m_GradientDetailsRadialGrid;
        private Border m_GradientDetailsRadialBorder;
        private Thumb m_GradientDetailsRadialTopThumb;
        private Thumb m_GradientDetailsRadialBottomThumb;
        private Ellipse m_GradientDetailsRadialEllipse;
        private Thumb m_GradientDetailsRadialCenterThumb;
        private TextBox m_GradientRadialCenterPointBox;
        private Point? m_ColorPosition;
        private Color m_color;
        private LinearGradientBrush m_LinearBrush;
        private RadialGradientBrush m_RadialBrush;
        private bool shouldFindPoint;
        private bool templateApplied;
        private bool isAlphaChange;

        private GradientStopCollection m_GradientBrushStopCollection;

        static GradientControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(GradientControl), new FrameworkPropertyMetadata(typeof(GradientControl)));
        }

        public GradientControl()
        {
            templateApplied = false;
            m_color = Colors.White;
            m_LinearBrush = new LinearGradientBrush();
            m_RadialBrush = new RadialGradientBrush();
            shouldFindPoint = true;
            SetValue(AProperty, m_color.A);
            SetValue(RProperty, m_color.R);
            SetValue(GProperty, m_color.G);
            SetValue(BProperty, m_color.B);
            SetValue(SelectedColorProperty, m_color);

            m_GradientBrushStopCollection = new GradientStopCollection();
            m_LinearBrush.GradientStops = m_GradientBrushStopCollection;
            m_GradientBrushStopCollection.Add(new GradientStop() { Color = (Color)ColorConverter.ConvertFromString("#FFFFFFFF"), Offset = 0 });
            m_GradientBrushStopCollection.Add(new GradientStop() { Color = (Color)ColorConverter.ConvertFromString("#FF000000"), Offset = 1 });

            SetValue(StartPointProperty, new Point(0, 0));
            SetValue(EndPointProperty, new Point(1, 1));
            SetValue(SelectedLinearBrushProperty, m_LinearBrush);
            SetValue(SelectedRadialBrushProperty, m_RadialBrush);
            SelectedLinearBrush.StartPoint = StartPoint;
            SelectedLinearBrush.EndPoint = EndPoint;
            SetValue(SelectedBrushTypeProperty, GradientBrushType.Linear);
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            m_ColorDetail = GetTemplateChild(ColorDetailName) as FrameworkElement;
            m_ColorMarker = GetTemplateChild(ColorMarkerName) as Path;
            m_ColorSlider = GetTemplateChild(ColorSliderName) as Slider;
            m_GradientTypeCombo = GetTemplateChild(GradientTypeComboName) as ComboBox;
            m_InterpModeCombo = GetTemplateChild("PART_InterpModeCombo") as ComboBox;
            m_SpreadMethodCombo = GetTemplateChild("PART_SpreadMethodCombo") as ComboBox;
            m_GradientDetailsLinearGrid = GetTemplateChild("PART_GradientDetailsLinearGrid") as Canvas;
            m_GradientDetailsLinearBorder = GetTemplateChild("PART_GradientDetailsLinearBorder") as Border;
            m_GradientDetailsLinearTopThumb = GetTemplateChild("PART_GradientDetailsLinearTopThumb") as Thumb;
            m_GradientDetailsLinearBottomThumb = GetTemplateChild("PART_GradientDetailsLinearBottomThumb") as Thumb;
            m_GradientStartPointBox = GetTemplateChild("PART_GradientStartPointBox") as TextBox;
            m_GradientEndPointBox = GetTemplateChild("PART_GradientEndPointBox") as TextBox;
            m_GradientStopSlider = GetTemplateChild("PART_GradientStopSlider") as Border;
            m_GradientStopDeatils = GetTemplateChild("PART_GradientStopDeatils") as Canvas;
            m_Gradient_DetailsOffsetText = GetTemplateChild("PART_Gradient_DetailsOffsetText") as TextBlock;
            m_Gradient_DetailsColorText = GetTemplateChild("PART_Gradient_DetailsColorText") as TextBlock;
            m_AddGradientstopButton = GetTemplateChild("PART_AddGradientstopButton") as Button;
            m_RemoveGradientstopButton = GetTemplateChild("PART_RemoveGradientstopButton") as Button;
            m_GradientDetailsStopAddBox = GetTemplateChild("PART_GradientDetailsStopAddBox") as TextBox;
            m_GradientDetailsStopRemoveBox = GetTemplateChild("PART_GradientDetailsStopRemoveBox") as TextBox;
            m_GradientDetailsRadialGrid = GetTemplateChild("PART_GradientDetailsRadialGrid") as Canvas;
            m_GradientDetailsRadialBorder = GetTemplateChild("PART_GradientDetailsRadialBorder") as Border;
            m_GradientDetailsRadialTopThumb = GetTemplateChild("PART_GradientDetailsRadialTopThumb") as Thumb;
            m_GradientDetailsRadialBottomThumb = GetTemplateChild("PART_GradientDetailsRadialBottomThumb") as Thumb;
            m_GradientDetailsRadialEllipse = GetTemplateChild("PART_GradientDetailsRadialEllipse") as Ellipse;
            m_GradientDetailsRadialCenterThumb = GetTemplateChild("PART_GradientDetailsRadialCenterThumb") as Thumb;
            m_GradientRadialCenterPointBox = GetTemplateChild("PART_GradientRadialCenterPointBox") as TextBox;
            m_ColorSlider.ValueChanged += new RoutedPropertyChangedEventHandler<double>(BaseColorChanged);

            m_ColorMarker.RenderTransform = markerTransform;
            m_GradientDetailsLinearTopThumb.RenderTransform = GradientDetailsLinearTopThumbTransform;
            m_GradientDetailsLinearTopThumb.RenderTransformOrigin = new Point(0.5, 0.5);
            m_GradientDetailsLinearBottomThumb.RenderTransform = GradientDetailsLinearBottomThumbTransform;
            m_GradientDetailsLinearBottomThumb.RenderTransformOrigin = new Point(0.5, 0.5);
            m_ColorMarker.RenderTransformOrigin = new Point(0.5, 0.5);
            m_ColorDetail.MouseLeftButtonDown += new MouseButtonEventHandler(OnMouseLeftButtonDown);
            m_ColorDetail.PreviewMouseMove += new MouseEventHandler(OnMouseMove);
            m_ColorDetail.SizeChanged += new SizeChangedEventHandler(ColorDetailSizeChanged);
            m_GradientTypeCombo.SelectionChanged += new SelectionChangedEventHandler(m_GradientTypeCombo_SelectionChanged);
            m_InterpModeCombo.SelectionChanged += new SelectionChangedEventHandler(m_InterpModeCombo_SelectionChanged);
            m_SpreadMethodCombo.SelectionChanged += new SelectionChangedEventHandler(m_SpreadMethodCombo_SelectionChanged);

            m_GradientDetailsLinearGrid.SizeChanged += new SizeChangedEventHandler(m_GradientDetailsLinearGrid_SizeChanged);
            m_GradientDetailsLinearGrid.PreviewMouseMove += new MouseEventHandler(m_GradientDetailsLinearGrid_PreviewMouseMove);
            m_GradientDetailsLinearTopThumb.DragDelta += new DragDeltaEventHandler(m_GradientDetailsLinearTopThumb_DragDelta);
            m_GradientDetailsLinearBottomThumb.DragDelta += new DragDeltaEventHandler(m_GradientDetailsLinearBottomThumb_DragDelta);
            m_GradientStopDeatils.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(m_GradientStopDeatils_PreviewMouseLeftButtonDown);
            m_AddGradientstopButton.Click += new RoutedEventHandler(m_AddGradientstopButton_Click);
            m_RemoveGradientstopButton.Click += new RoutedEventHandler(m_RemoveGradientstopButton_Click);
            m_GradientDetailsStopAddBox.TextChanged += new TextChangedEventHandler(m_GradientDetailsStopAddBox_TextChanged);
            m_GradientDetailsStopAddBox.GotFocus += new RoutedEventHandler(m_GradientDetailsStopAddBox_GotFocus);
            m_GradientDetailsStopRemoveBox.TextChanged += new TextChangedEventHandler(m_GradientDetailsStopRemoveBox_TextChanged);
            m_GradientDetailsStopRemoveBox.GotFocus += new RoutedEventHandler(m_GradientDetailsStopAddBox_GotFocus);
            m_GradientDetailsRadialGrid.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(m_GradientDetailsRadialGrid_PreviewMouseLeftButtonDown);
            m_GradientDetailsRadialCenterThumb.DragDelta += new DragDeltaEventHandler(m_GradientDetailsRadialCenterThumb_DragDelta);
            m_GradientDetailsRadialTopThumb.DragDelta += new DragDeltaEventHandler(m_GradientDetailsRadialTopThumb_DragDelta);
            m_GradientDetailsRadialBottomThumb.DragDelta += new DragDeltaEventHandler(m_GradientDetailsRadialBottomThumb_DragDelta);
            m_GradientStartPointBox.LostFocus += new RoutedEventHandler(m_GradientStartPointBox_LostFocus);
            m_GradientEndPointBox.LostFocus += new RoutedEventHandler(m_GradientEndPointBox_LostFocus);
            m_GradientRadialCenterPointBox.LostFocus += new RoutedEventHandler(m_GradientRadialCenterPointBox_LostFocus);

            templateApplied = true;
            shouldFindPoint = true;
            isAlphaChange = false;

            ///Change the button style
            ResourceDictionary resourceDictionary = new ResourceDictionary();
            resourceDictionary.Source = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            m_AddGradientstopButton.Resources = resourceDictionary;
            m_RemoveGradientstopButton.Resources = resourceDictionary;

            SetValue(X1Property, 0d);
            SetValue(X2Property, 0d);
            SetValue(Y1Property, 0d);
            SetValue(Y2Property, 0d);

            SelectedLinearBrush.SpreadMethod = SpreadMethod;
            SelectedLinearBrush.ColorInterpolationMode = InterpolationMode;

            GradientTopThumbLocation = new Point(0, 0);
            GradientBottomThumbLocation = new Point(m_GradientDetailsLinearGrid.RenderSize.Width, m_GradientDetailsLinearGrid.RenderSize.Height);

            SelectedColor = m_color;

            LinearGradientBrush brush = new LinearGradientBrush();
            brush.StartPoint = StartPoint;
            brush.EndPoint = EndPoint;
            brush.GradientStops = m_GradientBrushStopCollection;
            m_GradientStopSlider.Background = brush;

            //update the gradient stop 
            UpdateLinearBrushGradientStopThumb();
            SetValue(SelectedGradientStopProperty, m_GradientBrushStopCollection.OrderBy(b => b.Offset).First());
        }

        protected override void OnTemplateChanged(ControlTemplate oldTemplate, ControlTemplate newTemplate)
        {
            templateApplied = false;
            if (oldTemplate != null)
            {
                m_ColorSlider.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(BaseColorChanged);
                m_ColorDetail.MouseLeftButtonDown -= new MouseButtonEventHandler(OnMouseLeftButtonDown);
                m_ColorDetail.PreviewMouseMove -= new MouseEventHandler(OnMouseMove);
                m_ColorDetail.SizeChanged -= new SizeChangedEventHandler(ColorDetailSizeChanged);
                m_GradientDetailsLinearGrid.SizeChanged -= new SizeChangedEventHandler(m_GradientDetailsLinearGrid_SizeChanged);
                m_GradientDetailsLinearGrid.PreviewMouseMove -= new MouseEventHandler(m_GradientDetailsLinearGrid_PreviewMouseMove);
                m_ColorDetail = null;
                m_ColorMarker = null;
                m_ColorSlider = null;
                m_GradientDetailsLinearGrid = null;
                m_GradientDetailsLinearBottomThumb = null;
                m_GradientDetailsLinearTopThumb = null;
            }
            base.OnTemplateChanged(oldTemplate, newTemplate);
        }
        
        public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(System.Windows.Media.Color), typeof(GradientControl), new PropertyMetadata(System.Windows.Media.Colors.Transparent, new PropertyChangedCallback(SelectedColor_Changed)));

        public static readonly DependencyProperty SelectedLinearBrushProperty = DependencyProperty.Register("SelectedLinearBrush", typeof(System.Windows.Media.LinearGradientBrush), typeof(GradientControl), new PropertyMetadata(null));

        public static readonly DependencyProperty SelectedRadialBrushProperty = DependencyProperty.Register("SelectedRadialBrush", typeof(System.Windows.Media.RadialGradientBrush), typeof(GradientControl), new PropertyMetadata(null));

        public static readonly DependencyProperty SelectedGradientStopProperty = DependencyProperty.Register("SelectedGradientStop", typeof(GradientStop), typeof(GradientControl), new PropertyMetadata(null));

        public static readonly DependencyProperty AProperty = DependencyProperty.Register("A", typeof(byte), typeof(GradientControl), new PropertyMetadata((byte)255, new PropertyChangedCallback(AChanged)));

        public static readonly DependencyProperty RProperty = DependencyProperty.Register("R", typeof(byte), typeof(GradientControl), new PropertyMetadata((byte)255, new PropertyChangedCallback(RChanged)));

        public static readonly DependencyProperty GProperty = DependencyProperty.Register("G", typeof(byte), typeof(GradientControl), new PropertyMetadata((byte)255, new PropertyChangedCallback(GChanged)));

        public static readonly DependencyProperty BProperty = DependencyProperty.Register("B", typeof(byte), typeof(GradientControl), new PropertyMetadata((byte)255, new PropertyChangedCallback(BChanged)));

        public static readonly DependencyProperty HexadecimalStringProperty = DependencyProperty.Register("HexadecimalString", typeof(string), typeof(GradientControl), new PropertyMetadata("#FFFFFFFF", new PropertyChangedCallback(HexadecimalStringChanged)));

        public static readonly DependencyProperty StartPointProperty = DependencyProperty.Register("StartPoint", typeof(Point), typeof(GradientControl), new PropertyMetadata(new Point(0, 0)));

        public static readonly DependencyProperty EndPointProperty = DependencyProperty.Register("EndPoint", typeof(Point), typeof(GradientControl), new PropertyMetadata(new Point(0, 0)));

        public static readonly DependencyProperty X1Property = DependencyProperty.Register("X1", typeof(double), typeof(GradientControl), new PropertyMetadata((double)0));

        public static readonly DependencyProperty X2Property = DependencyProperty.Register("X2", typeof(double), typeof(GradientControl), new PropertyMetadata((double)0));

        public static readonly DependencyProperty Y1Property = DependencyProperty.Register("Y1", typeof(double), typeof(GradientControl), new PropertyMetadata((double)0));

        public static readonly DependencyProperty Y2Property = DependencyProperty.Register("Y2", typeof(double), typeof(GradientControl), new PropertyMetadata((double)0));

        public static readonly DependencyProperty CenterProperty = DependencyProperty.Register("Center", typeof(Point), typeof(GradientControl), new PropertyMetadata(new Point(0.5, 0.5)));

        public static readonly DependencyProperty GradientOriginProperty = DependencyProperty.Register("GradientOrigin", typeof(Point), typeof(GradientControl), new PropertyMetadata(new Point(0.5, 0.5)));

        public static readonly DependencyProperty RadiusXProperty = DependencyProperty.Register("RadiusX", typeof(double), typeof(GradientControl), new PropertyMetadata((double)0));

        public static readonly DependencyProperty RadiusYProperty = DependencyProperty.Register("RadiusY", typeof(double), typeof(GradientControl), new PropertyMetadata((double)0));

        public static readonly DependencyProperty SpreadMethodProperty = DependencyProperty.Register("SpreadMethod", typeof(GradientSpreadMethod), typeof(GradientControl), new PropertyMetadata(GradientSpreadMethod.Pad));

        public static readonly DependencyProperty InterpolationModeProperty = DependencyProperty.Register("InterpolationMode", typeof(ColorInterpolationMode), typeof(GradientControl), new PropertyMetadata(ColorInterpolationMode.SRgbLinearInterpolation));

        public static DependencyProperty SelectedBrushTypeProperty = DependencyProperty.Register("SelectedBrushType", typeof(GradientBrushType), typeof(GradientControl), new PropertyMetadata(GradientBrushType.Linear));

        public System.Windows.Media.Color SelectedColor
        {
            get { return (Color)GetValue(SelectedColorProperty); }
            set { SetValue(SelectedColorProperty, value); }
        }

        public System.Windows.Media.LinearGradientBrush SelectedLinearBrush
        {
            get { return (LinearGradientBrush)GetValue(SelectedLinearBrushProperty); }
            set { SetValue(SelectedLinearBrushProperty, value); }
        }

        public System.Windows.Media.RadialGradientBrush SelectedRadialBrush
        {
            get { return (RadialGradientBrush)GetValue(SelectedRadialBrushProperty); }
            set { SetValue(SelectedRadialBrushProperty, value); }
        }

        public GradientStop SelectedGradientStop
        {
            get { return (GradientStop)GetValue(SelectedGradientStopProperty); }
            set { SetValue(SelectedGradientStopProperty, value); }
        }

        public byte A
        {
            get { return (byte)GetValue(AProperty); }
            set { SetValue(AProperty, value); }
        }

        public byte R
        {
            get { return (byte)GetValue(RProperty); }
            set { SetValue(RProperty, value); }
        }

        public byte G
        {
            get { return (byte)GetValue(GProperty); }
            set { SetValue(GProperty, value); }
        }

        public byte B
        {
            get { return (byte)GetValue(BProperty); }
            set { SetValue(BProperty, value); }
        }

        public string HexadecimalString
        {
            get { return (string)GetValue(HexadecimalStringProperty); }
            set { SetValue(HexadecimalStringProperty, value); }
        }

        public Point StartPoint
        {
            get { return (Point)GetValue(StartPointProperty); }
            set { SetValue(StartPointProperty, value); }
        }

        public Point EndPoint
        {
            get { return (Point)GetValue(EndPointProperty); }
            set { SetValue(EndPointProperty, value); }
        }

        public double X1
        {
            get { return (double)GetValue(X1Property); }
            set { SetValue(X1Property, value); }
        }

        public double X2
        {
            get { return (double)GetValue(X2Property); }
            set { SetValue(X2Property, value); }
        }

        public double Y1
        {
            get { return (double)GetValue(Y1Property); }
            set { SetValue(Y1Property, value); }
        }

        public double Y2
        {
            get { return (double)GetValue(Y2Property); }
            set { SetValue(Y2Property, value); }
        }

        public Point Center
        {
            get { return (Point)GetValue(CenterProperty); }
            set { SetValue(CenterProperty, value); }
        }

        public Point GradientOrigin
        {
            get { return (Point)GetValue(GradientOriginProperty); }
            set { SetValue(GradientOriginProperty, value); }
        }

        public double RadiusX
        {
            get { return (double)GetValue(RadiusXProperty); }
            set { SetValue(RadiusXProperty, value); }
        }

        public double RadiusY
        {
            get { return (double)GetValue(RadiusYProperty); }
            set { SetValue(RadiusYProperty, value); }
        }

        public GradientSpreadMethod SpreadMethod
        {
            get { return (GradientSpreadMethod)GetValue(SpreadMethodProperty); }
            set { SetValue(SpreadMethodProperty, value); }
        }

        public ColorInterpolationMode InterpolationMode
        {
            get { return (ColorInterpolationMode)GetValue(InterpolationModeProperty); }
            set { SetValue(InterpolationModeProperty, value); }
        }

        public GradientBrushType SelectedBrushType
        {
            get { return (GradientBrushType)GetValue(SelectedBrushTypeProperty); }
            set { SetValue(SelectedBrushTypeProperty, value); }
        }

        public event RoutedPropertyChangedEventHandler<Brush> SelectedBrushChanged
        {
            add { AddHandler(SelectedBrushChangedEvent, value); }
            remove { RemoveHandler(SelectedBrushChangedEvent, value); }
        }

        public event RoutedPropertyChangedEventHandler<Color> SelectedColorChanged
        {
            add { AddHandler(SelectedColorChangedEvent, value); }
            remove { RemoveHandler(SelectedColorChangedEvent, value); }
        }

        protected virtual void OnAChanged(byte newValue)
        {
            m_color.A = newValue;
            SetValue(SelectedColorProperty, m_color);
        }

        private static void AChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            GradientControl c = (GradientControl)d;
            c.OnAChanged((byte)e.NewValue);
        }

        protected virtual void OnRChanged(byte newValue)
        {
            m_color.R = newValue;
            SetValue(SelectedColorProperty, m_color);
        }

        private static void RChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            GradientControl c = (GradientControl)d;
            c.OnRChanged((byte)e.NewValue);
        }

        protected virtual void OnGChanged(byte newValue)
        {
            m_color.G = newValue;
            SetValue(SelectedColorProperty, m_color);
        }

        private static void GChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            GradientControl c = (GradientControl)d;
            c.OnGChanged((byte)e.NewValue);
        }

        protected virtual void OnBChanged(byte newValue)
        {
            m_color.B = newValue;
            SetValue(SelectedColorProperty, m_color);
        }

        private static void BChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            GradientControl c = (GradientControl)d;
            c.OnBChanged((byte)e.NewValue);
        }

        protected virtual void OnHexadecimalStringChanged(string oldValue, string newValue)
        {
            try
            {
                if (shouldFindPoint)
                {
                    m_color = (Color)ColorConverter.ConvertFromString(newValue);
                }

                SetValue(AProperty, m_color.A);
                SetValue(RProperty, m_color.R);
                SetValue(GProperty, m_color.G);
                SetValue(BProperty, m_color.B);

                if (shouldFindPoint && !isAlphaChange && templateApplied)
                {
                    UpdateMarkerPosition(m_color);
                }
            }
            catch (FormatException)
            {
                SetValue(HexadecimalStringProperty, oldValue);
            }
        }

        private static void HexadecimalStringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            GradientControl c = (GradientControl)d;
            c.OnHexadecimalStringChanged((string)e.OldValue, (string)e.NewValue);
        }

        protected virtual void OnSelectedColorChanged(Color oldColor, Color newColor)
        {
            if (SelectedGradientStopProperty != null)
            {
                GradientStop stop = (GradientStop)GetValue(SelectedGradientStopProperty) as GradientStop;
                if (stop != null)
                {
                    Thumb thumb = GetGradientStopThumbFromGradientStop(stop);
                    if (thumb != null)
                        thumb.Background = new SolidColorBrush(newColor);
                    stop.Color = newColor;
                    m_Gradient_DetailsOffsetText.Text = "Offset : " + stop.Offset.ToString();
                    m_Gradient_DetailsColorText.Text = stop.Color.ToString();
                }
            }
            RoutedPropertyChangedEventArgs<Color> newEventArgs = new RoutedPropertyChangedEventArgs<Color>(oldColor, newColor);
            newEventArgs.RoutedEvent = GradientControl.SelectedColorChangedEvent;
            RaiseEvent(newEventArgs);
        }

        private static void SelectedColor_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            GradientControl cPicker = (GradientControl)d;
            cPicker.OnSelectedColorChanged((Color)e.OldValue, (Color)e.NewValue);
        }

        protected virtual void OnSelectedBrushChanged(Brush oldBrush, Brush newBrush)
        {
            RoutedPropertyChangedEventArgs<Brush> newEventArgs = new RoutedPropertyChangedEventArgs<Brush>(oldBrush, newBrush);
            newEventArgs.RoutedEvent = GradientControl.SelectedBrushChangedEvent;
            RaiseEvent(newEventArgs);
        }

        private static void SelectedBrush_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            GradientControl cPicker = (GradientControl)d;
            cPicker.OnSelectedBrushChanged((Brush)e.OldValue, (Brush)e.NewValue);
        }

        private void UpdateMarkerPosition(Point p)
        {
            markerTransform.X = p.X;
            markerTransform.Y = p.Y;
            p.X = p.X / m_ColorDetail.ActualWidth;
            p.Y = p.Y / m_ColorDetail.ActualHeight;
            if (p.X < -m_ColorMarker.ActualWidth / 2)
                p.X = -m_ColorMarker.ActualWidth / 2;
            else if (p.X > m_ColorDetail.ActualWidth + m_ColorMarker.ActualWidth / 2)
                p.X = m_ColorDetail.ActualWidth + m_ColorMarker.ActualWidth / 2;
            else if (p.Y < -m_ColorMarker.ActualHeight / 2)
                p.Y = -m_ColorMarker.ActualHeight / 2;
            else if (p.Y > m_ColorDetail.ActualHeight + m_ColorMarker.ActualHeight / 2)
                p.Y = m_ColorDetail.ActualHeight + m_ColorMarker.ActualHeight / 2;
            m_ColorPosition = p;
            DetermineColor(p);
        }

        private void UpdateMarkerPosition(Color theColor)
        {
            m_ColorPosition = null;
            HsvColor hsv = ColorHelper.ConvertRgbToHsv(theColor.R, theColor.G, theColor.B);

            m_ColorSlider.Value = hsv.H;

            Point p = new Point(hsv.S, 1 - hsv.V);

            m_ColorPosition = p;
            if (p.X == 0)
                p.X = p.X * m_ColorDetail.ActualWidth;
            else
                p.X = p.X * m_ColorDetail.ActualWidth;
            if (p.Y == 0)
                p.Y = p.Y * m_ColorDetail.ActualHeight;
            else
                p.Y = p.Y * m_ColorDetail.ActualHeight;
            markerTransform.X = p.X;
            markerTransform.Y = p.Y;
            if (theColor.R < 100 && theColor.G < 100 && theColor.B < 100)
                m_ColorMarker.Stroke = Brushes.White;
            else
                m_ColorMarker.Stroke = Brushes.Black;
        }

        private void DetermineColor(Point p)
        {
            HsvColor hsv = new HsvColor(360 - m_ColorSlider.Value, 1, 1);
            hsv.S = p.X;
            hsv.V = 1 - p.Y;
            m_color = ColorHelper.ConvertHsvToRgb(hsv.H, hsv.S, hsv.V);
            if (m_color.R < 100 && m_color.G < 100 && m_color.B < 100)
                m_ColorMarker.Stroke = Brushes.White;
            else
                m_ColorMarker.Stroke = Brushes.Black;
            shouldFindPoint = false;
            SetValue(HexadecimalStringProperty, m_color.ToString());
            shouldFindPoint = true;
        }

        private void ColorDetailSizeChanged(object sender, SizeChangedEventArgs args)
        {
            if (args.PreviousSize != Size.Empty &&
                args.PreviousSize.Width != 0 && args.PreviousSize.Height != 0)
            {
                double widthDifference = args.NewSize.Width / args.PreviousSize.Width;
                double heightDifference = args.NewSize.Height / args.PreviousSize.Height;
                if (markerTransform.X * widthDifference > m_ColorDetail.ActualWidth)
                    markerTransform.X = m_ColorDetail.ActualWidth + m_ColorMarker.ActualWidth / 2;
                else
                    markerTransform.X = markerTransform.X * widthDifference;
                if (markerTransform.Y * heightDifference > m_ColorDetail.ActualHeight)
                    markerTransform.Y = m_ColorDetail.ActualHeight + m_ColorMarker.ActualHeight / 2;
                else
                    markerTransform.Y = markerTransform.Y * heightDifference;
            }
            else if (m_ColorPosition != null)
            {
                markerTransform.X = ((Point)m_ColorPosition).X * args.NewSize.Width;
                markerTransform.Y = ((Point)m_ColorPosition).Y * args.NewSize.Height;
            }
        }
        
        private void BaseColorChanged(object sender, RoutedPropertyChangedEventArgs<Double> e)
        {
            if (m_ColorPosition != null)
            {
                DetermineColor((Point)m_ColorPosition);
            }
        }
        
        private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Point p = e.GetPosition(m_ColorDetail);
            UpdateMarkerPosition(p);
        }

        private void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                Point p = e.GetPosition(m_ColorDetail);
                UpdateMarkerPosition(p);
                Mouse.Synchronize();
            }
        }

        private void m_GradientDetailsLinearGrid_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            GradientTopThumbLocation = new Point(StartPoint.X * m_GradientDetailsLinearGrid.RenderSize.Width, StartPoint.Y * m_GradientDetailsLinearGrid.RenderSize.Height);
            GradientBottomThumbLocation = new Point(EndPoint.X * m_GradientDetailsLinearGrid.RenderSize.Width - 5, EndPoint.Y * m_GradientDetailsLinearGrid.RenderSize.Height - 5);
            UpdateGradientDetailsLinearThumbPosition();
        }

        private void m_GradientDetailsLinearGrid_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed && e.Source.GetType() == typeof(Path))
            {
                if (((Path)e.Source).Name.Equals("PART_GradientDetailsLinearTopThumb"))
                {
                    GradientTopThumbLocation = e.GetPosition(m_GradientDetailsLinearGrid);
                    UpdateGradientDetailsLinearThumbPosition();
                    Mouse.Synchronize();
                }
                else if (((Path)e.Source).Name.Equals("PART_GradientDetailsLinearBottomThumb"))
                {
                    GradientBottomThumbLocation = e.GetPosition(m_GradientDetailsLinearGrid);
                    UpdateGradientDetailsLinearThumbPosition();
                    Mouse.Synchronize();
                }
            }
        }

        private void UpdateGradientDetailsLinearThumbPosition()
        {
            Canvas.SetLeft(m_GradientDetailsLinearTopThumb, GradientTopThumbLocation.X);
            Canvas.SetTop(m_GradientDetailsLinearTopThumb, GradientTopThumbLocation.Y);
            Canvas.SetLeft(m_GradientDetailsLinearBottomThumb, GradientBottomThumbLocation.X);
            Canvas.SetTop(m_GradientDetailsLinearBottomThumb, GradientBottomThumbLocation.Y);

            SetValue(X1Property, GradientTopThumbLocation.X + m_GradientDetailsLinearTopThumb.Width / 2);
            SetValue(Y1Property, GradientTopThumbLocation.Y + m_GradientDetailsLinearTopThumb.Height / 2);
            SetValue(X2Property, GradientBottomThumbLocation.X - m_GradientDetailsLinearBottomThumb.Width / 2);
            SetValue(Y2Property, GradientBottomThumbLocation.Y - m_GradientDetailsLinearBottomThumb.Height / 2);
        }

        private void UpdateGradientDetailsRadialThumbLocation()
        {
            m_GradientDetailsRadialEllipse.Width = m_GradientDetailsRadialBorder.Width;
            m_GradientDetailsRadialEllipse.Height = m_GradientDetailsRadialBorder.Height;
            Canvas.SetLeft(m_GradientDetailsRadialEllipse, 5);
            Canvas.SetTop(m_GradientDetailsRadialEllipse, 5);
            Canvas.SetTop(m_GradientDetailsRadialCenterThumb, Canvas.GetTop(m_GradientDetailsRadialEllipse) + m_GradientDetailsRadialEllipse.Height / 2 - m_GradientDetailsRadialCenterThumb.Height / 2);
            Canvas.SetLeft(m_GradientDetailsRadialCenterThumb, Canvas.GetTop(m_GradientDetailsRadialEllipse) + m_GradientDetailsRadialEllipse.Width / 2 - m_GradientDetailsRadialCenterThumb.Width / 2);

            Canvas.SetLeft(m_GradientDetailsRadialBottomThumb, Canvas.GetLeft(m_GradientDetailsRadialEllipse) + m_GradientDetailsRadialEllipse.Width - m_GradientDetailsRadialBottomThumb.Width / 2);
            Canvas.SetTop(m_GradientDetailsRadialBottomThumb, Canvas.GetTop(m_GradientDetailsRadialEllipse) + m_GradientDetailsRadialEllipse.Height / 2 - m_GradientDetailsRadialBottomThumb.ActualHeight / 2);
            Canvas.SetLeft(m_GradientDetailsRadialTopThumb, Canvas.GetLeft(m_GradientDetailsRadialEllipse) + m_GradientDetailsRadialEllipse.Width / 2 - m_GradientDetailsRadialTopThumb.Width / 2);
            Canvas.SetTop(m_GradientDetailsRadialTopThumb, Canvas.GetTop(m_GradientDetailsRadialEllipse) - m_GradientDetailsRadialTopThumb.Height / 2);
            ((Thumb)m_GradientStopDeatils.Children.OfType<Thumb>().FirstOrDefault()).Focus();
        }

        private void m_GradientDetailsLinearTopThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            Canvas.SetLeft(m_GradientDetailsLinearTopThumb, Canvas.GetLeft(m_GradientDetailsLinearTopThumb) + e.HorizontalChange);
            Canvas.SetTop(m_GradientDetailsLinearTopThumb, Canvas.GetTop(m_GradientDetailsLinearTopThumb) + e.VerticalChange);

            if (Canvas.GetLeft(m_GradientDetailsLinearTopThumb) < 0)
                Canvas.SetLeft(m_GradientDetailsLinearTopThumb, 0);
            if (Canvas.GetTop(m_GradientDetailsLinearTopThumb) < 0)
                Canvas.SetTop(m_GradientDetailsLinearTopThumb, 0);
            if (Canvas.GetLeft(m_GradientDetailsLinearTopThumb) > m_GradientDetailsLinearGrid.RenderSize.Width - m_GradientDetailsLinearTopThumb.Width / 2)
                Canvas.SetLeft(m_GradientDetailsLinearTopThumb, m_GradientDetailsLinearGrid.RenderSize.Width - m_GradientDetailsLinearTopThumb.Width / 2);
            if (Canvas.GetTop(m_GradientDetailsLinearTopThumb) > m_GradientDetailsLinearGrid.RenderSize.Height - m_GradientDetailsLinearTopThumb.Height / 2)
                Canvas.SetTop(m_GradientDetailsLinearTopThumb, m_GradientDetailsLinearGrid.RenderSize.Height - m_GradientDetailsLinearTopThumb.Height / 2);

            Point pt = new Point(Canvas.GetLeft(m_GradientDetailsLinearTopThumb) + m_GradientDetailsLinearTopThumb.Width / 2, Canvas.GetTop(m_GradientDetailsLinearTopThumb) + m_GradientDetailsLinearTopThumb.Height / 2);
            SetValue(X1Property, pt.X);
            SetValue(Y1Property, pt.Y);

            double XX;
            double YY;
            if (pt.X >= m_GradientDetailsLinearGrid.RenderSize.Width)
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width, 2);
            else
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width - 0.03, 2);
            if (pt.Y >= m_GradientDetailsLinearGrid.RenderSize.Height)
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height, 2);
            else
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height - 0.03, 2);
            SetValue(StartPointProperty, new Point(XX, YY));
            SelectedLinearBrush.StartPoint = StartPoint;
        }

        private void m_GradientDetailsLinearBottomThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            Canvas.SetLeft(m_GradientDetailsLinearBottomThumb, Canvas.GetLeft(m_GradientDetailsLinearBottomThumb) + e.HorizontalChange);
            Canvas.SetTop(m_GradientDetailsLinearBottomThumb, Canvas.GetTop(m_GradientDetailsLinearBottomThumb) + e.VerticalChange);

            if (Canvas.GetLeft(m_GradientDetailsLinearBottomThumb) < 0)
                Canvas.SetLeft(m_GradientDetailsLinearBottomThumb, 0);
            if (Canvas.GetTop(m_GradientDetailsLinearBottomThumb) < 0)
                Canvas.SetTop(m_GradientDetailsLinearBottomThumb, 0);
            if (Canvas.GetLeft(m_GradientDetailsLinearBottomThumb) > m_GradientDetailsLinearGrid.RenderSize.Width - m_GradientDetailsLinearBottomThumb.Width / 2)
                Canvas.SetLeft(m_GradientDetailsLinearBottomThumb, m_GradientDetailsLinearGrid.RenderSize.Width - m_GradientDetailsLinearBottomThumb.Width / 2);
            if (Canvas.GetTop(m_GradientDetailsLinearBottomThumb) > m_GradientDetailsLinearGrid.RenderSize.Height - m_GradientDetailsLinearBottomThumb.Height / 2)
                Canvas.SetTop(m_GradientDetailsLinearBottomThumb, m_GradientDetailsLinearGrid.RenderSize.Height - m_GradientDetailsLinearBottomThumb.Height / 2);

            Point pt = new Point(Canvas.GetLeft(m_GradientDetailsLinearBottomThumb) + m_GradientDetailsLinearBottomThumb.Width / 2, Canvas.GetTop(m_GradientDetailsLinearBottomThumb) + m_GradientDetailsLinearBottomThumb.Height / 2);
            SetValue(X2Property, pt.X);
            SetValue(Y2Property, pt.Y);

            double XX;
            double YY;
            if (pt.X >= m_GradientDetailsLinearGrid.RenderSize.Width)
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width, 2);
            else
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width - 0.03, 2);
            if (pt.Y >= m_GradientDetailsLinearGrid.RenderSize.Height)
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height, 2);
            else
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height - 0.03, 2);
            SetValue(EndPointProperty, new Point(XX, YY));
            SelectedLinearBrush.EndPoint = EndPoint;
        }

        private Point GradientTopThumbLocation
        {
            get;
            set;
        }

        private Point GradientBottomThumbLocation
        {
            get;
            set;
        }

        private void UpdateLinearBrushGradientStopThumb()
        {            
            var list = m_GradientStopDeatils.Children.OfType<UIElement>().ToList();
            list.RemoveAll(bb => bb.GetType() == typeof(Thumb));

            int index = 1;
            foreach (GradientStop stop in m_GradientBrushStopCollection)
            {
                Thumb thumb = new Thumb();
                thumb.Name = "GradientDetailsStopThumb" + index;
                thumb.Width = 12;
                thumb.Height = 9;
                thumb.Background = new SolidColorBrush(stop.Color);
                Style style = this.FindResource("GradientStopThumbStyle") as Style;
                thumb.Style = style;
                thumb.Focusable = true;
                thumb.ApplyTemplate();
                thumb.DragDelta += new DragDeltaEventHandler(GradientStopThumb_DragDelta);
                m_GradientStopDeatils.Children.Add(thumb);
                Canvas.SetLeft(thumb, Canvas.GetLeft(m_GradientStopSlider) + m_GradientStopSlider.Width - thumb.Width / 2);
                if (stop.Offset == 0)
                    Canvas.SetTop(thumb, stop.Offset * m_GradientStopSlider.Height);
                else if (stop.Offset == 1)
                    Canvas.SetTop(thumb, stop.Offset * m_GradientStopSlider.Height - thumb.Height);
                else
                    Canvas.SetTop(thumb, stop.Offset * m_GradientStopSlider.Height - thumb.Height / 2);
                index += 1;
            }

            ((Thumb)m_GradientStopDeatils.Children.OfType<Thumb>().FirstOrDefault()).Focus();

            Thumb thum = (Thumb)m_GradientStopDeatils.Children.OfType<Thumb>().FirstOrDefault() as Thumb;
            double offset;
            if (Canvas.GetTop(thum) == 0)
                offset = 0;
            else if (Canvas.GetTop(thum) + thum.Height == m_GradientStopDeatils.Height)
                offset = 1;
            else
                offset = Math.Round((Canvas.GetTop(thum) + thum.Height / 2) / m_GradientStopDeatils.Height, 2);

            GradientStop gStop = GetGradientStopFromOffset(offset);
            m_Gradient_DetailsOffsetText.Text = "Offset : " + gStop.Offset.ToString();
            m_Gradient_DetailsColorText.Text = gStop.Color.ToString();
        }

        private void GradientStopThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            Thumb thumb = sender as Thumb;
            double offset;
            if (Canvas.GetTop(thumb) == 0)
                offset = 0;
            else if (Canvas.GetTop(thumb) + thumb.Height == m_GradientStopDeatils.Height)
                offset = 1;
            else
                offset = Math.Round((Canvas.GetTop(thumb) + thumb.Height / 2) / m_GradientStopDeatils.Height, 2);

            GradientStop stop = GetGradientStopFromOffset(offset);
            
            Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange);
            if (Canvas.GetTop(thumb) <= 0)
                Canvas.SetTop(thumb, 0);
            else if (Canvas.GetTop(thumb) + thumb.Height >= m_GradientStopDeatils.Height)
                Canvas.SetTop(thumb, m_GradientStopDeatils.Height - thumb.Height);

            if (Canvas.GetTop(thumb) == 0)
                offset = 0;
            else if (Canvas.GetTop(thumb) + thumb.Height == m_GradientStopDeatils.Height)
                offset = 1;
            else
                offset = Math.Round((Canvas.GetTop(thumb) + thumb.Height / 2) / m_GradientStopDeatils.Height, 2);

            stop.Offset = offset;
            m_Gradient_DetailsOffsetText.Text = "Offset : " + stop.Offset.ToString();
            m_Gradient_DetailsColorText.Text = stop.Color.ToString();
        }

        private void m_GradientStopDeatils_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.Source.GetType() == typeof(Thumb))
            {
                Thumb thumb = e.Source as Thumb;
                thumb.Focus();
                double offset;
                if (Canvas.GetTop(thumb) == 0)
                    offset = 0;
                else if (Canvas.GetTop(thumb) + thumb.Height == m_GradientStopDeatils.Height)
                    offset = 1;
                else
                    offset = Math.Round((Canvas.GetTop(thumb) + thumb.Height / 2) / m_GradientStopDeatils.Height, 2);
                GradientStop stop = GetGradientStopFromOffset(offset);
                SetValue(SelectedGradientStopProperty, stop);
                SetValue(SelectedColorProperty, ((SolidColorBrush)thumb.Background).Color);
                UpdateMarkerPosition(((SolidColorBrush)thumb.Background).Color);
                stop = (GradientStop)GetValue(SelectedGradientStopProperty) as GradientStop;
                m_Gradient_DetailsOffsetText.Text = "Offset : " + stop.Offset.ToString();
                m_Gradient_DetailsColorText.Text = stop.Color.ToString();
            }
        }

        private GradientStop GetGradientStopFromOffset(double offset)
        {
            foreach (GradientStop stop in this.m_GradientBrushStopCollection)
            {
                if (stop.Offset.Equals(offset))
                    return stop;
            }
            return null;
        }

        private Thumb GetGradientStopThumbFromGradientStop(GradientStop stop)
        {
            Thumb thumb = null;
            foreach (var thum in this.m_GradientStopDeatils.Children)
            {
                if (thum.GetType() == typeof(Thumb))
                {
                    double offset;
                    if (Canvas.GetTop((Thumb)thum) == 0)
                        offset = 0;
                    else if (Canvas.GetTop((Thumb)thum) + ((Thumb)thum).Height == m_GradientStopDeatils.Height)
                        offset = 1;
                    else
                        offset = Math.Round((Canvas.GetTop((Thumb)thum) + ((Thumb)thum).Height / 2) / m_GradientStopDeatils.Height, 2);
                    if (offset.Equals(stop.Offset) && ((SolidColorBrush)((Thumb)thum).Background).Color.Equals(stop.Color))
                        thumb = (Thumb)thum as Thumb;
                }
            }
            return thumb;
        }

        private void RemoveGradientDetailsThumbFromChildrent()
        {
            var list = m_GradientStopDeatils.Children.OfType<Thumb>().ToList();

            foreach (var child in list)
            {
                this.m_GradientStopDeatils.Children.Remove(child);
            }
        }

        private void m_GradientTypeCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (m_GradientTypeCombo.SelectedIndex == 0)
            {
                RemoveGradientDetailsThumbFromChildrent();
                m_GradientBrushStopCollection = new GradientStopCollection();
                m_LinearBrush.SpreadMethod = SpreadMethod;
                m_LinearBrush.GradientStops = m_GradientBrushStopCollection;
                m_GradientBrushStopCollection.Add(new GradientStop() { Color = (Color)ColorConverter.ConvertFromString("#FFFFFFFF"), Offset = 0 });
                m_GradientBrushStopCollection.Add(new GradientStop() { Color = (Color)ColorConverter.ConvertFromString("#FF000000"), Offset = 1 });

                SetValue(StartPointProperty, new Point(0, 0));
                SetValue(EndPointProperty, new Point(1, 1));
                SetValue(SelectedLinearBrushProperty, m_LinearBrush);
                SetValue(SelectedRadialBrushProperty, m_RadialBrush);
                SelectedLinearBrush.StartPoint = StartPoint;
                SelectedLinearBrush.EndPoint = EndPoint;

                LinearGradientBrush brush = new LinearGradientBrush();
                brush.StartPoint = StartPoint;
                brush.EndPoint = EndPoint;
                brush.GradientStops = m_GradientBrushStopCollection;
                m_GradientStopSlider.Background = brush;

                UpdateGradientDetailsLinearThumbPosition();

                //update the gradient stop 
                UpdateLinearBrushGradientStopThumb();
                SetValue(SelectedGradientStopProperty, m_GradientBrushStopCollection.OrderBy(b => b.Offset).First());
                SetValue(SelectedBrushTypeProperty, GradientBrushType.Linear);
            }
            else if (m_GradientTypeCombo.SelectedIndex == 1)
            {
                m_GradientBrushStopCollection = new GradientStopCollection();
                m_LinearBrush.GradientStops = m_GradientBrushStopCollection;
                m_GradientBrushStopCollection.Add(new GradientStop() { Color = (Color)ColorConverter.ConvertFromString("#FFFFFFFF"), Offset = 0 });
                m_GradientBrushStopCollection.Add(new GradientStop() { Color = (Color)ColorConverter.ConvertFromString("#FF000000"), Offset = 1 });

                SetValue(CenterProperty, new Point(0.5, 0.5));
                SetValue(GradientOriginProperty, new Point(0.5, 0.5));
                SetValue(RadiusXProperty, 0.5);
                SetValue(RadiusYProperty, 0.5);

                RadialGradientBrush brush = new RadialGradientBrush();
                brush.Center = Center;
                brush.GradientOrigin = GradientOrigin;
                brush.RadiusX = RadiusX;
                brush.RadiusY = RadiusY;
                brush.SpreadMethod = SpreadMethod;
                brush.ColorInterpolationMode = InterpolationMode;
                brush.GradientStops = m_GradientBrushStopCollection;
                SetValue(SelectedRadialBrushProperty, brush);
                UpdateGradientDetailsRadialThumbLocation();
                SetValue(SelectedBrushTypeProperty, GradientBrushType.Radial);
            }
        }

        private void m_InterpModeCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            SetValue(SelectedGradientStopProperty, null);
            m_Gradient_DetailsOffsetText.Text = "";
            m_Gradient_DetailsColorText.Text = "";

            if(m_InterpModeCombo.SelectedIndex==0)
                SetValue(InterpolationModeProperty, ColorInterpolationMode.SRgbLinearInterpolation);
            else
                SetValue(InterpolationModeProperty, ColorInterpolationMode.ScRgbLinearInterpolation);

            SelectedLinearBrush.ColorInterpolationMode = InterpolationMode;
            SelectedRadialBrush.ColorInterpolationMode = InterpolationMode;
        }

        private void m_SpreadMethodCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            SetValue(SelectedGradientStopProperty, null);
            m_Gradient_DetailsOffsetText.Text = "";
            m_Gradient_DetailsColorText.Text = "";

            if (m_SpreadMethodCombo.SelectedIndex == 0)
                SetValue(SpreadMethodProperty, GradientSpreadMethod.Pad);
            else if (m_SpreadMethodCombo.SelectedIndex == 1)
                SetValue(SpreadMethodProperty, GradientSpreadMethod.Reflect);
            else if (m_SpreadMethodCombo.SelectedIndex == 2)
                SetValue(SpreadMethodProperty, GradientSpreadMethod.Repeat);

            SelectedLinearBrush.SpreadMethod = SpreadMethod;
            SelectedRadialBrush.SpreadMethod = SpreadMethod;
        }

        private void m_AddGradientstopButton_Click(object sender, RoutedEventArgs e)
        {
            var text = m_GradientDetailsStopAddBox.Text;

            if (string.IsNullOrEmpty(text))
            {
                MessageBox.Show("Value must not empty !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                m_GradientDetailsStopAddBox.Focus();
                return;
            }

            if (!Information.IsNumeric(text))
            {
                MessageBox.Show("Value must be numeric type !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                m_GradientDetailsStopAddBox.Focus();
                return;
            }

            if (Convert.ToDouble(text) < 0)
            {
                MessageBox.Show("Value must be zero or greater than zero !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                m_GradientDetailsStopAddBox.Focus();
                return;
            }

            if (Convert.ToDouble(text) > 1)
            {
                MessageBox.Show("Value must be 1 or less than 1 !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                m_GradientDetailsStopAddBox.Focus();
                return;
            }

            double offset = Convert.ToDouble(text);
            GradientStop stop = GetGradientStopFromOffset(offset);
            if (stop != null)
            {
                MessageBox.Show("A gradient stop already exists in same offset !!! " + Constants.vbCrLf + "Please Enter a different value for stop. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                m_GradientDetailsStopAddBox.Focus();
                return;
            }

            stop = new GradientStop() { Offset = offset, Color = SelectedColor };
            m_GradientBrushStopCollection.Add(stop);
            UpdateLinearBrushGradientStopThumb();
        }

        private void m_GradientDetailsStopAddBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (!Information.IsNumeric(m_GradientDetailsStopAddBox.Text))
                m_GradientDetailsStopAddBox.Text = "";
        }

        private void m_GradientDetailsStopAddBox_GotFocus(object sender, RoutedEventArgs e)
        {
            SetValue(SelectedGradientStopProperty, null);
        }

        private void m_GradientDetailsStopRemoveBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (!Information.IsNumeric(m_GradientDetailsStopRemoveBox.Text))
                m_GradientDetailsStopRemoveBox.Text = "";
        }

        private void m_GradientDetailsRadialGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.Source.GetType() != typeof(Thumb))
            {
                Point pt = e.GetPosition(m_GradientDetailsRadialGrid);
                SetValue(GradientOriginProperty, new Point(Math.Round(pt.X / m_GradientDetailsRadialGrid.Width, 2), Math.Round(pt.Y / m_GradientDetailsRadialGrid.Height, 2)));
                SelectedRadialBrush.GradientOrigin = GradientOrigin;
            }
        }

        private void m_GradientDetailsRadialCenterThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            Canvas.SetLeft(m_GradientDetailsRadialCenterThumb, Canvas.GetLeft(m_GradientDetailsRadialCenterThumb) + e.HorizontalChange);
            Canvas.SetTop(m_GradientDetailsRadialCenterThumb, Canvas.GetTop(m_GradientDetailsRadialCenterThumb) + e.VerticalChange);

            if (Canvas.GetLeft(m_GradientDetailsRadialCenterThumb) - m_GradientDetailsRadialCenterThumb.Width / 2 < 0)
                Canvas.SetLeft(m_GradientDetailsRadialCenterThumb, m_GradientDetailsRadialCenterThumb.Width / 2);
            if (Canvas.GetTop(m_GradientDetailsRadialCenterThumb) - m_GradientDetailsRadialCenterThumb.Height / 2 < 0)
                Canvas.SetTop(m_GradientDetailsRadialCenterThumb, m_GradientDetailsRadialCenterThumb.Height / 2);
            if (Canvas.GetLeft(m_GradientDetailsRadialCenterThumb) + m_GradientDetailsRadialCenterThumb.Width > m_GradientDetailsRadialGrid.Width)
                Canvas.SetLeft(m_GradientDetailsRadialCenterThumb, m_GradientDetailsRadialGrid.Width - m_GradientDetailsRadialCenterThumb.Width);
            if (Canvas.GetTop(m_GradientDetailsRadialCenterThumb) + m_GradientDetailsRadialCenterThumb.Height > m_GradientDetailsRadialGrid.Height)
                Canvas.SetTop(m_GradientDetailsRadialCenterThumb, m_GradientDetailsRadialGrid.Height - m_GradientDetailsRadialCenterThumb.Height);

            Canvas.SetLeft(m_GradientDetailsRadialEllipse, Canvas.GetLeft(m_GradientDetailsRadialCenterThumb) + m_GradientDetailsRadialCenterThumb.Width / 2 - m_GradientDetailsRadialEllipse.Width / 2);
            Canvas.SetTop(m_GradientDetailsRadialEllipse, Canvas.GetTop(m_GradientDetailsRadialCenterThumb) + m_GradientDetailsRadialCenterThumb.Height / 2 - m_GradientDetailsRadialEllipse.Height / 2);

            Canvas.SetLeft(m_GradientDetailsRadialBottomThumb, Canvas.GetLeft(m_GradientDetailsRadialEllipse) + m_GradientDetailsRadialEllipse.Width - m_GradientDetailsRadialBottomThumb.Width / 2);
            Canvas.SetTop(m_GradientDetailsRadialBottomThumb, Canvas.GetTop(m_GradientDetailsRadialEllipse) + m_GradientDetailsRadialEllipse.Height / 2 - m_GradientDetailsRadialBottomThumb.Height / 2);
            Canvas.SetLeft(m_GradientDetailsRadialTopThumb, Canvas.GetLeft(m_GradientDetailsRadialEllipse) + m_GradientDetailsRadialEllipse.Width / 2 - m_GradientDetailsRadialTopThumb.Width / 2);
            Canvas.SetTop(m_GradientDetailsRadialTopThumb, Canvas.GetTop(m_GradientDetailsRadialEllipse) - m_GradientDetailsRadialTopThumb.Height / 2);

            if (Canvas.GetTop(m_GradientDetailsRadialTopThumb) < 0)
                m_GradientDetailsRadialTopThumb.Visibility = System.Windows.Visibility.Collapsed;
            else if (Canvas.GetTop(m_GradientDetailsRadialTopThumb) > m_GradientDetailsRadialGrid.Height)
                m_GradientDetailsRadialTopThumb.Visibility = System.Windows.Visibility.Collapsed;
            else if (Canvas.GetLeft(m_GradientDetailsRadialTopThumb) < 0)
                m_GradientDetailsRadialTopThumb.Visibility = System.Windows.Visibility.Collapsed;
            else if (Canvas.GetLeft(m_GradientDetailsRadialTopThumb) > m_GradientDetailsRadialGrid.Width)
                m_GradientDetailsRadialTopThumb.Visibility = System.Windows.Visibility.Collapsed;
            else
                m_GradientDetailsRadialTopThumb.Visibility = System.Windows.Visibility.Visible;

            if (Canvas.GetTop(m_GradientDetailsRadialBottomThumb) < 0)
                m_GradientDetailsRadialBottomThumb.Visibility = System.Windows.Visibility.Collapsed;
            else if (Canvas.GetTop(m_GradientDetailsRadialBottomThumb) > m_GradientDetailsRadialGrid.Height)
                m_GradientDetailsRadialBottomThumb.Visibility = System.Windows.Visibility.Collapsed;
            else if (Canvas.GetLeft(m_GradientDetailsRadialBottomThumb) < 0)
                m_GradientDetailsRadialBottomThumb.Visibility = System.Windows.Visibility.Collapsed;
            else if (Canvas.GetLeft(m_GradientDetailsRadialBottomThumb) > m_GradientDetailsRadialGrid.Width)
                m_GradientDetailsRadialBottomThumb.Visibility = System.Windows.Visibility.Collapsed;
            else
                m_GradientDetailsRadialBottomThumb.Visibility = System.Windows.Visibility.Visible;

            double PointX = (Canvas.GetLeft(m_GradientDetailsRadialCenterThumb) + m_GradientDetailsRadialCenterThumb.Width / 2) / m_GradientDetailsRadialEllipse.Width;
            double PointY = (Canvas.GetTop(m_GradientDetailsRadialCenterThumb) + m_GradientDetailsRadialCenterThumb.Height / 2) / m_GradientDetailsRadialEllipse.Height;
            SetValue(CenterProperty, new Point(Math.Round(PointX, 2), Math.Round(PointY, 2)));
            SelectedRadialBrush.Center = Center;
        }

        private void m_GradientDetailsRadialTopThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            double temp;
            temp = this.m_GradientDetailsRadialEllipse.ActualHeight;
            if (this.m_GradientDetailsRadialEllipse.ActualHeight - e.VerticalChange < this.m_GradientDetailsRadialBorder.ActualHeight && this.m_GradientDetailsRadialEllipse.ActualHeight - e.VerticalChange > this.m_GradientDetailsRadialCenterThumb.ActualHeight / 2)
                this.m_GradientDetailsRadialEllipse.Height = this.m_GradientDetailsRadialEllipse.ActualHeight - e.VerticalChange;
            Canvas.SetTop(m_GradientDetailsRadialEllipse, Canvas.GetTop(m_GradientDetailsRadialCenterThumb) + m_GradientDetailsRadialCenterThumb.ActualHeight / 2 - m_GradientDetailsRadialEllipse.ActualHeight / 2);

            Canvas.SetLeft(m_GradientDetailsRadialTopThumb, Canvas.GetLeft(m_GradientDetailsRadialEllipse) + m_GradientDetailsRadialEllipse.Width / 2 - m_GradientDetailsRadialTopThumb.Width / 2);
            Canvas.SetTop(m_GradientDetailsRadialTopThumb, Canvas.GetTop(m_GradientDetailsRadialEllipse) - m_GradientDetailsRadialTopThumb.Height / 2);

            m_GradientDetailsRadialEllipse.InvalidateVisual();
            SetValue(RadiusYProperty, Math.Round(((m_GradientDetailsRadialEllipse.ActualHeight / 2) / m_GradientDetailsRadialBorder.ActualHeight), 2));
            SelectedRadialBrush.RadiusY = Math.Round(((m_GradientDetailsRadialEllipse.ActualHeight / 2) / m_GradientDetailsRadialBorder.ActualHeight), 2);
            RadialGradientBrush brush = (RadialGradientBrush)m_GradientDetailsRadialBorder.Background;
            brush.RadiusY = Math.Round(((m_GradientDetailsRadialEllipse.ActualHeight / 2) / m_GradientDetailsRadialBorder.ActualHeight), 2);
        }

        private void m_GradientDetailsRadialBottomThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            double temp;
            temp = this.m_GradientDetailsRadialEllipse.ActualWidth;
            if (this.m_GradientDetailsRadialEllipse.ActualWidth + e.HorizontalChange < this.m_GradientDetailsRadialBorder.ActualWidth && this.m_GradientDetailsRadialEllipse.ActualWidth + e.HorizontalChange > this.m_GradientDetailsRadialCenterThumb.ActualWidth / 2)
                this.m_GradientDetailsRadialEllipse.Width = this.m_GradientDetailsRadialEllipse.ActualWidth + e.HorizontalChange;
            Canvas.SetLeft(m_GradientDetailsRadialEllipse, Canvas.GetLeft(m_GradientDetailsRadialCenterThumb) + m_GradientDetailsRadialCenterThumb.ActualWidth / 2 - m_GradientDetailsRadialEllipse.ActualWidth / 2);

            Canvas.SetLeft(m_GradientDetailsRadialBottomThumb, Canvas.GetLeft(m_GradientDetailsRadialEllipse) + m_GradientDetailsRadialEllipse.Width - m_GradientDetailsRadialBottomThumb.Width / 2);
            Canvas.SetTop(m_GradientDetailsRadialBottomThumb, Canvas.GetTop(m_GradientDetailsRadialEllipse) + m_GradientDetailsRadialEllipse.ActualHeight / 2 - m_GradientDetailsRadialBottomThumb.ActualHeight / 2);

            m_GradientDetailsRadialEllipse.InvalidateVisual();
            SetValue(RadiusXProperty, Math.Round(((m_GradientDetailsRadialEllipse.ActualWidth / 2) / m_GradientDetailsRadialBorder.ActualWidth), 2));
            SelectedRadialBrush.RadiusX = Math.Round(((m_GradientDetailsRadialEllipse.ActualWidth / 2) / m_GradientDetailsRadialBorder.ActualWidth), 2);
            RadialGradientBrush brush = (RadialGradientBrush)m_GradientDetailsRadialBorder.Background;
            brush.RadiusX = Math.Round(((m_GradientDetailsRadialEllipse.ActualWidth / 2) / m_GradientDetailsRadialBorder.ActualWidth), 2);
        }

        private void m_GradientStartPointBox_LostFocus(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(m_GradientStartPointBox.Text))
            {
                MessageBox.Show("Value can't be null !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            if (Strings.InStr(m_GradientStartPointBox.Text, ",") < 0)
            {
                MessageBox.Show("Invalid value entered !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            string[] arr = m_GradientStartPointBox.Text.Split(',');

            if (string.IsNullOrEmpty(arr[0]) | !Information.IsNumeric(arr[0]))
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be Numeric type. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            if (string.IsNullOrEmpty(arr[1]) | !Information.IsNumeric(arr[1]))
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be Numeric type. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            double x = Convert.ToDouble(arr[0]);
            double y = Convert.ToDouble(arr[1]);

            if (x > 1 | x < 0)
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be less than or equal 1 and greater or equal 0. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            if (y > 1 | y < 0)
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be less than or equal 1 and greater or equal 0. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            double coX = Math.Round(x * m_GradientDetailsLinearGrid.ActualWidth - m_GradientDetailsLinearTopThumb.Width / 2, 2);
            double coY = Math.Round(y * m_GradientDetailsLinearGrid.ActualHeight - m_GradientDetailsLinearTopThumb.Height / 2, 2);

            Canvas.SetLeft(m_GradientDetailsLinearTopThumb, coX);
            Canvas.SetTop(m_GradientDetailsLinearTopThumb, coY);

            if (Canvas.GetLeft(m_GradientDetailsLinearTopThumb) < 0)
                Canvas.SetLeft(m_GradientDetailsLinearTopThumb, 0);
            if (Canvas.GetTop(m_GradientDetailsLinearTopThumb) < 0)
                Canvas.SetTop(m_GradientDetailsLinearTopThumb, 0);
            if (Canvas.GetLeft(m_GradientDetailsLinearTopThumb) > m_GradientDetailsLinearGrid.RenderSize.Width - m_GradientDetailsLinearTopThumb.Width / 2)
                Canvas.SetLeft(m_GradientDetailsLinearTopThumb, m_GradientDetailsLinearGrid.RenderSize.Width - m_GradientDetailsLinearTopThumb.Width / 2);
            if (Canvas.GetTop(m_GradientDetailsLinearTopThumb) > m_GradientDetailsLinearGrid.RenderSize.Height - m_GradientDetailsLinearTopThumb.Height / 2)
                Canvas.SetTop(m_GradientDetailsLinearTopThumb, m_GradientDetailsLinearGrid.RenderSize.Height - m_GradientDetailsLinearTopThumb.Height / 2);

            Point pt = new Point(Canvas.GetLeft(m_GradientDetailsLinearTopThumb) + m_GradientDetailsLinearTopThumb.Width / 2, Canvas.GetTop(m_GradientDetailsLinearTopThumb) + m_GradientDetailsLinearTopThumb.Height / 2);
            SetValue(X1Property, pt.X);
            SetValue(Y1Property, pt.Y);

            double XX;
            double YY;
            if (pt.X >= m_GradientDetailsLinearGrid.RenderSize.Width)
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width, 2);
            else
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width - 0.03, 2);
            if (pt.Y >= m_GradientDetailsLinearGrid.RenderSize.Height)
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height, 2);
            else
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height - 0.03, 2);
            SetValue(StartPointProperty, new Point(XX, YY));
            SelectedLinearBrush.StartPoint = StartPoint;

            pt = new Point(Canvas.GetLeft(m_GradientDetailsLinearBottomThumb) + m_GradientDetailsLinearBottomThumb.Width / 2, Canvas.GetTop(m_GradientDetailsLinearBottomThumb) + m_GradientDetailsLinearBottomThumb.Height / 2);
            SetValue(X2Property, pt.X);
            SetValue(Y2Property, pt.Y);

            if (pt.X >= m_GradientDetailsLinearGrid.RenderSize.Width)
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width, 2);
            else
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width - 0.03, 2);
            if (pt.Y >= m_GradientDetailsLinearGrid.RenderSize.Height)
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height, 2);
            else
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height - 0.03, 2);
            SetValue(EndPointProperty, new Point(XX, YY));
            SelectedLinearBrush.EndPoint = EndPoint;
        }

        private void m_GradientEndPointBox_LostFocus(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(m_GradientEndPointBox.Text))
            {
                MessageBox.Show("Value can't be null !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            if (Strings.InStr(m_GradientEndPointBox.Text, ",") < 0)
            {
                MessageBox.Show("Invalid value entered !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            string[] arr = m_GradientEndPointBox.Text.Split(',');

            if (string.IsNullOrEmpty(arr[0]) | !Information.IsNumeric(arr[0]))
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be Numeric type. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            if (string.IsNullOrEmpty(arr[1]) | !Information.IsNumeric(arr[1]))
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be Numeric type. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            double x = Convert.ToDouble(arr[0]);
            double y = Convert.ToDouble(arr[1]);

            if (x > 1 | x < 0)
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be less than or equal 1 and greater or equal 0. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            if (y > 1 | y < 0)
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be less than or equal 1 and greater or equal 0. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            double coX = Math.Round(x * m_GradientDetailsLinearGrid.ActualWidth - m_GradientDetailsLinearTopThumb.Width / 2, 2);
            double coY = Math.Round(y * m_GradientDetailsLinearGrid.ActualHeight - m_GradientDetailsLinearTopThumb.Height / 2, 2);

            Canvas.SetLeft(m_GradientDetailsLinearBottomThumb, coX);
            Canvas.SetTop(m_GradientDetailsLinearBottomThumb, coY);

            if (Canvas.GetLeft(m_GradientDetailsLinearBottomThumb) < 0)
                Canvas.SetLeft(m_GradientDetailsLinearBottomThumb, 0);
            if (Canvas.GetTop(m_GradientDetailsLinearBottomThumb) < 0)
                Canvas.SetTop(m_GradientDetailsLinearBottomThumb, 0);
            if (Canvas.GetLeft(m_GradientDetailsLinearBottomThumb) > m_GradientDetailsLinearGrid.RenderSize.Width - m_GradientDetailsLinearBottomThumb.Width / 2)
                Canvas.SetLeft(m_GradientDetailsLinearBottomThumb, m_GradientDetailsLinearGrid.RenderSize.Width - m_GradientDetailsLinearBottomThumb.Width / 2);
            if (Canvas.GetTop(m_GradientDetailsLinearBottomThumb) > m_GradientDetailsLinearGrid.RenderSize.Height - m_GradientDetailsLinearBottomThumb.Height / 2)
                Canvas.SetTop(m_GradientDetailsLinearBottomThumb, m_GradientDetailsLinearGrid.RenderSize.Height - m_GradientDetailsLinearBottomThumb.Height / 2);

            Point pt = new Point(Canvas.GetLeft(m_GradientDetailsLinearTopThumb) + m_GradientDetailsLinearTopThumb.Width / 2, Canvas.GetTop(m_GradientDetailsLinearTopThumb) + m_GradientDetailsLinearTopThumb.Height / 2);
            SetValue(X1Property, pt.X);
            SetValue(Y1Property, pt.Y);

            double XX;
            double YY;
            if (pt.X >= m_GradientDetailsLinearGrid.RenderSize.Width)
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width, 2);
            else
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width - 0.03, 2);
            if (pt.Y >= m_GradientDetailsLinearGrid.RenderSize.Height)
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height, 2);
            else
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height - 0.03, 2);
            SetValue(StartPointProperty, new Point(XX, YY));
            SelectedLinearBrush.StartPoint = StartPoint;

            pt = new Point(Canvas.GetLeft(m_GradientDetailsLinearBottomThumb) + m_GradientDetailsLinearBottomThumb.Width / 2, Canvas.GetTop(m_GradientDetailsLinearBottomThumb) + m_GradientDetailsLinearBottomThumb.Height / 2);
            SetValue(X2Property, pt.X);
            SetValue(Y2Property, pt.Y);

            if (pt.X >= m_GradientDetailsLinearGrid.RenderSize.Width)
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width, 2);
            else
                XX = Math.Round(pt.X / m_GradientDetailsLinearGrid.RenderSize.Width - 0.03, 2);
            if (pt.Y >= m_GradientDetailsLinearGrid.RenderSize.Height)
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height, 2);
            else
                YY = Math.Round(pt.Y / m_GradientDetailsLinearGrid.RenderSize.Height - 0.03, 2);
            SetValue(EndPointProperty, new Point(XX, YY));
            SelectedLinearBrush.EndPoint = EndPoint;
        }

        private void m_GradientRadialCenterPointBox_LostFocus(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(m_GradientRadialCenterPointBox.Text))
            {
                MessageBox.Show("Value can't be null !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            if (Strings.InStr(m_GradientRadialCenterPointBox.Text, ",") < 0)
            {
                MessageBox.Show("Invalid value entered !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            string[] arr = m_GradientRadialCenterPointBox.Text.Split(',');

            if (string.IsNullOrEmpty(arr[0]) | !Information.IsNumeric(arr[0]))
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be Numeric type. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            if (string.IsNullOrEmpty(arr[1]) | !Information.IsNumeric(arr[1]))
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be Numeric type. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            double x = Convert.ToDouble(arr[0]);
            double y = Convert.ToDouble(arr[1]);

            if (x > 1 | x < 0)
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be less than or equal 1 and greater or equal 0. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            if (y > 1 | y < 0)
            {
                MessageBox.Show("Invalid value entered !!! " + Constants.vbCrLf + "Value must be less than or equal 1 and greater or equal 0. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Warning);
                m_GradientStartPointBox.Text = "";
                m_GradientStartPointBox.Focus();
                return;
            }

            double PointX = (Canvas.GetLeft(m_GradientDetailsRadialCenterThumb) + m_GradientDetailsRadialCenterThumb.Width / 2) / m_GradientDetailsRadialBorder.Width;
            double PointY = (Canvas.GetTop(m_GradientDetailsRadialCenterThumb) + m_GradientDetailsRadialCenterThumb.Height / 2) / m_GradientDetailsRadialBorder.Height;
        }

        private void m_RemoveGradientstopButton_Click(object sender, RoutedEventArgs e)
        {
            var text = m_GradientDetailsStopRemoveBox.Text;

            if (string.IsNullOrEmpty(text))
            {
                MessageBox.Show("Value must not empty !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                m_GradientDetailsStopRemoveBox.Focus();
                return;
            }

            if (!Information.IsNumeric(text))
            {
                MessageBox.Show("Value must be numeric type !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                m_GradientDetailsStopRemoveBox.Focus();
                return;
            }

            if (Convert.ToDouble(text) < 0)
            {
                MessageBox.Show("Value must be zero or greater than zero !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                m_GradientDetailsStopRemoveBox.Focus();
                return;
            }

            if (Convert.ToDouble(text) > 1)
            {
                MessageBox.Show("Value must be 1 or less than 1 !!! ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                m_GradientDetailsStopRemoveBox.Focus();
                return;
            }

            double offset = Convert.ToDouble(text);
            GradientStop stop = GetGradientStopFromOffset(offset);
            if (stop == null)
            {
                MessageBox.Show("Gradient stop does not exists in gradient collection !!! " + Constants.vbCrLf + "Please Enter a different value for stop. ", "YagnaColor", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                m_GradientDetailsStopRemoveBox.Focus();
                return;
            }

            m_GradientBrushStopCollection.Remove(stop);
            UpdateLinearBrushGradientStopThumb();
        }
    }
}
